package com.iot.core.manager.job;

import com.iot.core.util.MyDateTime;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;

import java.util.Date;
import java.util.Properties;
import java.util.Set;

@Slf4j
public class DbJobManager {
    @Autowired
    private Environment environment;
    @Autowired
    private Scheduler scheduler;

    private static   DbJobManager instance = null;
    //2.构造方法设为 private
    public DbJobManager() {
      instance=this;
    }
    public static DbJobManager getInstance() {

        return instance;
    }

    Properties getProperties(){
        Properties prop = new Properties();
        prop.put("org.quartz.scheduler.instanceName", "FreeterScheduler");
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        //线程池配置
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "10");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        //JobStore配置
        prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
        //集群配置
        prop.put("org.quartz.jobStore.isClustered", "true");
        prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
        prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
        prop.put("org.quartz.jobStore.misfireThreshold", "12000");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        //默认执行
        prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
        return prop;
    }

    public void start() throws  Exception {

        var s=scheduler.getSchedulerInstanceId();
        var startAt=new Date();
        startAt= MyDateTime.addSecond(startAt,5);//5秒后执行

        Class superClass=Class.forName("com.iot.core.manager.job.IMyDbJob");

        Reflections reflections = new Reflections("com.iot");
        Set<Class<?>> annotated = reflections.getSubTypesOf(superClass);
        for (Class<?> clazz : annotated) {
            var mjob=(IMyDbJob) clazz.getDeclaredConstructor().newInstance()  ;
            //2、任务实例（JobDetail）
            var jobDetail= JobBuilder.newJob((Class<  ? extends Job>) clazz) //加载任务类，与HelloJob完成绑定，要求HelloJob实现Job接口
                    .withIdentity(mjob.getJobName(),mjob.getJobGroup() ) //参数1：任务的名称（唯一实例）；参数2：任务组的名称
                    .build();
            //3、触发器（Trigger）
            var trigger= TriggerBuilder.newTrigger()
                    .withIdentity(mjob.getJobName(),mjob.getJobGroup()) //参数1：触发器的名称（唯一实例）；参数2：触发器组的名称
                    .startAt(startAt)
                    .withSchedule(  CronScheduleBuilder.cronSchedule(mjob.getCron() )   ) //每5秒执行一次
                    .build();
            if(scheduler.checkExists(jobDetail.getKey())){
                scheduler.deleteJob(jobDetail.getKey() );
            }


            //让调度器关联任务和触发器，保证按照触发器定义的条件执行任务
            scheduler.scheduleJob(jobDetail,trigger);
        }

        //启动
        scheduler.start();
    }

}
